//
//  BLOperation.m
//  CALayer
//
//  Created by Benz.L on 21/08/2018.
//  Copyright © 2018 BenzL. All rights reserved.
//

#import "BLOperation.h"

@interface BLOperation()
@property (nonatomic, strong) NSRecursiveLock *lock;
@end

@implementation BLOperation
@synthesize executing = _executing;
@synthesize finished = _finished;
@synthesize cancelled = _cancelled;

- (instancetype)init {
    self = [super init];
    if (self) {
        _lock = [NSRecursiveLock new];
    }
    return self;
}

- (void)start {
    @autoreleasepool {
        [_lock lock];
        if ([self isCancelled]) {
            self.finished = YES;
            self.executing = NO;
        }
        else {
            self.executing = YES;
            if (_executeBlock) {
                _executeBlock(self);
            }
        }
        [_lock unlock];
    }
}

- (void)cancel {
    [_lock lock];
    if (![self isCancelled]) {
        [super cancel];
        self.cancelled = YES;
        if ([self isExecuting]) {
            self.executing = NO;
            self.finished = YES;
        }
    }
    [_lock unlock];
}

- (void)setExecuting:(BOOL)executing {
    [_lock lock];
    if (_executing != executing) {
        [self willChangeValueForKey:@"isExecuting"];
        _executing = executing;
        [self didChangeValueForKey:@"isExecuting"];
    }
    [_lock unlock];
}

- (BOOL)isExecuting {
    [_lock lock];
    BOOL executing = _executing;
    [_lock unlock];
    return executing;
}

- (void)setFinished:(BOOL)finished {
    [_lock lock];
    if (_finished != finished) {
        [self willChangeValueForKey:@"isFinished"];
        _finished = finished;
        [self didChangeValueForKey:@"isFinished"];
    }
    [_lock unlock];
}

- (BOOL)isFinished {
    [_lock lock];
    BOOL finished = _finished;
    [_lock unlock];
    return finished;
}

- (void)setCancelled:(BOOL)cancelled {
    [_lock lock];
    if (_cancelled != cancelled) {
        [self willChangeValueForKey:@"isCancelled"];
        _cancelled = cancelled;
        [self didChangeValueForKey:@"isCancelled"];
    }
    [_lock unlock];
}

- (BOOL)isCancelled {
    [_lock lock];
    BOOL cancelled = _cancelled;
    [_lock unlock];
    return cancelled;
}

- (void)markAsFinised {
    self.finished = YES;
}

@end
